package core;

import java.util.Map;

import javazoom.jlgui.basicplayer.BasicController;
import javazoom.jlgui.basicplayer.BasicPlayerEvent;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import javazoom.jlgui.basicplayer.BasicPlayerListener;
import events.LibraryChangeEvent;
import events.LibraryListener;
import gui.SongTable;

public class QueueRunner implements Runnable, BasicPlayerListener,
		LibraryListener {

	private final AuroraPlayer player;
	private final SongTable queue;
	private final Thread thread;
	private Song current = null;

	public QueueRunner(AuroraPlayer player, SongTable queue) {
		this.player = player;
		this.queue = queue;
		queue.getLibrary().addLibraryListener(this);
		player.addBasicPlayerListener(this);
		thread = new Thread(this);
		thread.setDaemon(true);
		thread.start();
	}

	public void run() {
		while (thread != null) {
			synchronized (this) {
				try {
					wait();
				} catch (InterruptedException e) {
				}
				if (current != null) {
					// make sure that it is still the current song in the queue
					if (queue.getLibrary().getSongAt(0) != current) {
						try {
							player.stop();
						} catch (BasicPlayerException e) {
							e.printStackTrace();
						}
						current = null;
					}
				}
				if (current == null && queue.getLibrary().getNumSongs() > 0) {
					current = queue.getLibrary().getSongAt(0);
					player.play(current);
				}
			}
		}
	}

	@Override
	public void opened(Object stream, Map<?, ?> properties) {
		// TODO Auto-generated method stub

	}

	@Override
	public void progress(int bytesread, long microseconds, byte[] pcmdata,
			Map<?, ?> properties) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setController(BasicController controller) {
		// TODO Auto-generated method stub

	}

	@Override
	public void stateUpdated(BasicPlayerEvent event) {
		if (event.getCode() == BasicPlayerEvent.EOM) {
			synchronized (this) {
				queue.getLibrary().removeSong(current);
				current = null;
				notify();
			}
		}
	}

	@Override
	public synchronized void libraryChanged(LibraryChangeEvent e) {
		synchronized (this) {
			notify();
		}
	}

}
